package controllers

import (
	"encoding/json"
	"fmt"
	"github.com/beego/beego/v2/core/logs"
	"personal-skill/constants"
	"personal-skill/lib"
	"personal-skill/models"
	"personal-skill/util/encryptutil"
	"personal-skill/util/pageutil"
	"personal-skill/util/redisutil"
	"personal-skill/util/resultutil"
	"strconv"
	"strings"
)

type UserController struct {
	BaseController
}

// Get 根据id获取用户信息
func (userController *UserController) Get() {
	userId, err := userController.GetInt64("id")
	if err != nil {
		userController.ResponseJson(resultutil.Error(resultutil.UnknownErr))
	}
	user := models.User{
		Id: userId,
	}
	err = user.GetById()
	if err != nil {
		userController.ResponseJson(resultutil.Error(resultutil.UserNotFoundErr))
	}

	userController.ResponseJson(resultutil.SuccessWithData(models.UserPageResp{
		Id:            user.Id,
		Username:      user.Username,
		LastLoginTime: lib.TranslateTimeFrom(user.LastLoginTime),
		CreateTime:    lib.TranslateTimeFrom(user.CreateTime),
		UpdateTime:    lib.TranslateTimeFrom(user.UpdateTime),
	}))
}

// Post 添加用户
func (userController *UserController) Post() {
	userAddParams := models.UserAddParams{}
	err := json.Unmarshal(userController.Ctx.Input.RequestBody, &userAddParams)
	if err != nil {
		logs.Error(err)
		userController.ResponseJson(resultutil.Error(resultutil.RequestParamErr))
	}
	var errMsg string
	isErr := false
	if userAddParams.Username == "" {
		errMsg = "用户名不能为空"
		isErr = true
	}
	if userAddParams.Password == "" {
		if isErr {
			errMsg += "且密码不能为空"
		} else {
			errMsg = "密码不能为空"
			isErr = true
		}
	}
	if isErr {
		userController.ResponseJson(resultutil.ErrorWithMsg(resultutil.UserAddFailErr, errMsg))
	}
	user := models.User{}
	userInDB, err := user.GetByUserName(userAddParams.Username)
	if userInDB != nil && userInDB.Username != "" {
		userController.ResponseJson(resultutil.Error(resultutil.UserAlreadyExistErr))
	}
	encryptPwd := encryptutil.Md5(userAddParams.Password)
	user.Password = encryptPwd
	user.Username = userAddParams.Username
	role := models.Role{
		RoleNo: userAddParams.RoleNo,
	}
	err = role.GetByRoleNo()
	if err != nil {
		logs.Error(err)
		userController.ResponseJson(resultutil.Error(resultutil.UserAddFailErr))
	}
	user.Role = &role

	var userMenuList []*models.Menu
	userMenuMap := make(map[string]*models.Menu, 20)
	for _, menuNo := range userAddParams.Menus {
		menu := models.GetByMenuNo(menuNo)
		if menu != nil {
			userMenuMap[menu.MenuNo] = menu
			GetDescendantNodes(menuNo, &userMenuMap)
		}
	}
	for _, menu := range userMenuMap {
		userMenuList = append(userMenuList, menu)
	}
	user.Menus = userMenuList
	_, err = user.Save()
	if err != nil {
		userController.ResponseJson(resultutil.Error(resultutil.UserAddFailErr))
	}
	userController.ResponseJson(resultutil.Success())
}

func GetDescendantNodes(menuNo string, res *map[string]*models.Menu) {
	menus, count, _ := models.NewMenu().GetBySuperMenuNo(menuNo)
	if count > 0 {
		for _, menu := range menus {
			(*res)[menu.MenuNo] = menu
			GetDescendantNodes(menu.MenuNo, res)
		}
	}
}

// Delete 删除用户信息
func (userController *UserController) Delete() {
	userId, err := userController.GetInt64("id")
	if err != nil {
		userController.ResponseJson(resultutil.ErrorWithMsg(resultutil.RequestParamErr, "解析id为int值出错"))
	}
	user := models.User{Id: userId}
	err = user.DelLogic()
	if err != nil {
		userController.ResponseJson(resultutil.Error(resultutil.UserDelFailErr))
	}
	userController.ResponseJson(resultutil.Success())

}

// Put 更新用户信息
func (userController *UserController) Put() {
	user := models.User{}
	data := userController.Ctx.Input.RequestBody
	err := json.Unmarshal(data, &user)
	if err != nil {
		userController.ResponseJson(resultutil.ErrorWithMsg(resultutil.RequestParamErr, "解析请求参数到user出错"))
	}
	checkUser := models.User{Id: user.Id}
	err = checkUser.GetById()
	if err != nil || checkUser.Username == "" {
		userController.ResponseJson(resultutil.Error(resultutil.UserNotFoundErr))
	}
	_, err = user.Update()
	if err != nil {
		userController.ResponseJson(resultutil.Error(resultutil.UserAddFailErr))
	}
	userController.ResponseJson(resultutil.Success())
}

// PageList 分页查询
func (userController *UserController) PageList() {
	user := models.User{}
	params, err := json.Marshal(userController.Ctx.Input.RequestBody)
	if err != nil {
		logs.Error(err)
		return
	}
	fmt.Println(string(params))

	pageSize, err := userController.GetInt("pageSize")
	if err != nil {
		logs.Error(err)
		userController.ResponseJson(resultutil.ErrorWithMsg(resultutil.RequestParamErr, "解析pageSize为int值出错"))
	}
	pageIndex, err := userController.GetInt("pageIndex")
	if err != nil {
		userController.ResponseJson(resultutil.ErrorWithMsg(resultutil.RequestParamErr, "解析pageIndex为int值出错"))
	}
	username := userController.GetString("username")
	user.Username = username
	userList, total, err := user.PageList(pageIndex, pageSize)
	if err != nil {
		userController.ResponseJson(resultutil.ErrorWithMsg(resultutil.UserNotFoundErr, "未查询到用户信息"))
	}
	userController.ResponseJson(resultutil.SuccessWithData(pageutil.Page(pageIndex, pageSize, total, userList)))
}

// GetMenuList 获取用户菜单权限
func (userController *UserController) GetMenuList() {
	userId, err := userController.GetInt64("userId")
	if err != nil {
		userController.ResponseJson(resultutil.Error(resultutil.RequestParamErr))
	}
	cacheKey := constants.RedisKeyUserMenu + strconv.FormatInt(userId, 10)
	str, err2 := redisutil.GetStr(cacheKey)
	if err2 == nil && strings.TrimSpace(str) != "" {
		item := models.MenuTreeItem{}
		err2 := json.Unmarshal([]byte(str), &item)
		if err2 == nil {
			userController.ResponseJson(resultutil.SuccessWithData(item))
		}
	}
	user := models.User{Id: userId}
	list := user.GetMenuList()
	menuTree, err := models.BuildSingleRootMenuTree(list)
	if err != nil {
		userController.ResponseJson(resultutil.Error(resultutil.MenuNotFoundErr))
	}
	marshalJson, err := json.Marshal(menuTree)
	if err == nil {
		err := redisutil.SetStr(cacheKey, string(marshalJson), constants.DefaultCacheTime)
		if err != nil {
		}
	}
	userController.ResponseJson(resultutil.SuccessWithData(menuTree))
}

func (userController *UserController) GetSkillList() {
	fmt.Println("获取技能列表")
	user := models.User{Id: 1}
	list := user.GetSkillList()
	userController.ResponseJson(resultutil.SuccessWithData(list))
}
